/*
 * Copyright 2014, General Dynamics C4 Systems
 *
 * SPDX-License-Identifier: GPL-2.0-only
 */

#pragma once

#include <config.h>

#ifdef CONFIG_IOMMU

#include <types.h>
#include <api/failures.h>
#include <object/structures.h>
#include <plat_mode/machine/hardware_gen.h>
#include <plat/machine/pci.h>
/*Z 返回PCI总线号，即根表索引。0～255 */
static inline int vtd_get_root_index(dev_id_t dev)
{
    return get_pci_bus(dev);
}
/*Z 返回PCI设备号和功能号。0~255，左5位设备号，右3位功能号 */
static inline int vtd_get_context_index(dev_id_t dev)
{
    return dev & 0xff;
}

struct lookupIOPTSlot_ret {
    exception_t status;
    vtd_pte_t  *ioptSlot;   /*Z 页表项地址。level不为0时本项指向最后一个有效页表项 */
    int         level;      /*Z 剩余的页表级数。不为0意味着某级页表不存在 */
};
typedef struct lookupIOPTSlot_ret lookupIOPTSlot_ret_t;/*Z 查找IOMMU页表结果 */

cap_t master_iospace_cap(void);
exception_t decodeX86IOPTInvocation(word_t invLabel, word_t length, cte_t *slot, cap_t cap, extra_caps_t excaps,
                                    word_t  *buffer);
exception_t decodeX86IOMapInvocation(word_t length, cte_t *slot, cap_t cap, extra_caps_t excaps, word_t *buffer);
exception_t decodeX86IOSpaceInvocation(word_t invLabel, cap_t cap);
exception_t performX86IOUnMapInvocation(cap_t cap, cte_t *ctSlot);
void unmapIOPage(cap_t cap);/*Z 清除能力代表的内存页在IOMMU中的页表项，清缓存 */
void deleteIOPageTable(cap_t cap);
void unmapVTDContextEntry(cap_t cap);/*Z 删除IOMMU上下文表中能力对应的表项，刷新cache和IOTLB，置当前线程为重启动 */

#endif /* CONFIG_IOMMU */

